package com.dc.handler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

//Controller增强器 拦截所有@controller控制器
//最常用的就是全局异常处理
@ControllerAdvice
public class ControllerExceptionHandler {

    //获取日志对象
    private final Logger logger = LoggerFactory.getLogger(this.getClass());


    //如果需要将异常传导到页面上，需要使用ModelAndView作为返回值
    @ExceptionHandler(Exception.class)//指明异常的处理类型
    public ModelAndView exceptionHander(HttpServletRequest request, Exception e) throws Exception {
        //日志记录下异常信息  会在控制台输出
        logger.error("Requst URL : {}，Exception : {}", request.getRequestURL(),e);

        //如果发生的异常带有ResponseStatus注解交由Spring Boot本身自己去处理，不走下面的mv操作
        if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
            throw e;
        }

        ModelAndView mv = new ModelAndView();
        mv.addObject("url",request.getRequestURL());
        mv.addObject("exception", e);
        mv.setViewName("error/error");
        return mv;
    }

    //统一拦截所有Exception，做统一处理（日志记录），并将信息返回指定的页面
/*    @ControllerAdvice 的使用
    当被@Controller标识的类里没有定义异常处理器时，
    当程序抛出异常时，将会调用被@ControllerAdvice标识类里被@ExceptionHandler标识的方法。*/

}
